package com.printer.bluetooth.android;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Handler;
import android.util.Log;

import com.printer.bluetooth.android.util.Utils;

public class BluetoothPrinter {

	private static final String TAG = "BluetoothPrinter";
	private boolean needVerify = false;
	private BluetoothDevice btDevice;
	private BluetoothSocket btSocket;
	private BluetoothAdapter btAdapt;
	private OutputStream sendStream;
	private InputStream receiveStream;
	private Handler printerHandler;
	public static final int Handler_Connect_Connecting = 100;
	public static final int Handler_Connect_Success = 101;
	public static final int Handler_Connect_Failed = 102;
	public static final int Handler_Connect_Closed = 103;
	public static final int Handler_Message_Error = 104;
	public static final int Handler_Message_Read = 105;
	private String printerName = "";
	private String macAddress = "";
	private String mEncoding;
	private boolean autoReceive = false;
	private boolean isConnected = false;
	private String SDK_Vesion = "2.3";
	private PrinterType currentPrintType = PrinterType.T9;
	private String companyTitle;
	private String companySubTitle;
	private Bitmap companyLogo;
	private List<String> tableData;
	private String tableReg;
	private String[] tableLine;
	private int two_dimensional_param1;
	private int two_dimensional_param2;
	private int two_dimensional_param3;
	private HashMap<Integer, String> unPrintColumnMap;
	private int[] tableColWidth;
	private byte currentBarCodeType;
	private final UUID PRINTER_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
	private final String printerCompanyName = "company";
	private String separator_T9 = "==============================================\n";
	private String separator_T3 = "==============================\n";
	public static final int COMM_INIT_PRINTER = 0;
	public static final int COMM_WAKE_PRINTER = 1;
	public static final int COMM_PRINT_AND_RETURN_STANDARD = 2;
	public static final int COMM_PRINT_AND_NEWLINE = 3;
	public static final int COMM_PRINT_AND_ENTER = 4;
	public static final int COMM_MOVE_NEXT_TAB_POSITION = 5;
	public static final int COMM_DEF_LINE_SPACING = 6;
	public static final int COMM_PRINT_AND_WAKE_PAPER_BY_LNCH = 0;
	public static final int COMM_PRINT_AND_WAKE_PAPER_BY_LINE = 1;
	public static final int COMM_CLOCKWISE_ROTATE_90 = 4;
	public static final int COMM_ALIGN = 13;
	public static final int COMM_ALIGN_LEFT = 0;
	public static final int COMM_ALIGN_CENTER = 1;
	public static final int COMM_ALIGN_RIGHT = 2;
	public static final int COMM_LINE_HEIGHT = 10;
	public static final int COMM_CHARACTER_RIGHT_MARGIN = 11;
	public static final byte BAR_CODE_TYPE_UPC_A = 0;
	public static final byte BAR_CODE_TYPE_UPC_E = 1;
	public static final byte BAR_CODE_TYPE_JAN13 = 2;
	public static final byte BAR_CODE_TYPE_JAN8 = 3;
	public static final byte BAR_CODE_TYPE_CODE39 = 4;
	public static final byte BAR_CODE_TYPE_ITF = 5;
	public static final byte BAR_CODE_TYPE_CODABAR = 6;
	public static final byte BAR_CODE_TYPE_CODE93 = 72;
	public static final byte BAR_CODE_TYPE_CODE128 = 73;
	public static final byte BAR_CODE_TYPE_PDF417 = 100;
	public static final byte BAR_CODE_TYPE_DATAMATRIX = 101;
	public static final byte BAR_CODE_TYPE_QRCODE = 102;
	private Thread thread;

	public String getEncoding() {

		return this.mEncoding;
	}

	public void setEncoding(String mEncoding) {

		this.mEncoding = mEncoding;
	}

	public void setAutoReceiveData(boolean auto) {

		this.autoReceive = auto;
	}

	public void setHandler(Handler mHandler) {

		this.printerHandler = mHandler;
	}

	public PrinterType getCurrentPrintType() {

		return this.currentPrintType;
	}

	public void setCurrentPrintType(PrinterType currentPrintType) {

		this.currentPrintType = currentPrintType;
	}

	public String getSDK_Vesion() {

		return this.SDK_Vesion;
	}

	public String getCompanyName() {

		return "company";
	}

	public boolean isConnected() {

		return this.isConnected;
	}

	public String getMacAddress() {

		return this.macAddress;
	}

	@Deprecated
	public String getFriendName() {

		return getPrinterName();
	}

	public String getPrinterName() {

		return this.printerName;
	}

	public BluetoothPrinter(BluetoothDevice device) {

		this.btDevice = device;
		if (this.btDevice != null) {
			this.printerName = this.btDevice.getName();
			this.macAddress = this.btDevice.getAddress();
		}
	}

	public BluetoothPrinter(String macAddress, int flag) {

		this.btAdapt = BluetoothAdapter.getDefaultAdapter();
		try {
			this.btDevice = this.btAdapt.getRemoteDevice(macAddress.toUpperCase());
		} catch (Exception e) {
			e.printStackTrace();
			this.btDevice = null;
		}
		if (this.btDevice != null) {
			this.printerName = this.btDevice.getName();
			macAddress = this.btDevice.getAddress();
		}
	}

	@Deprecated
	public BluetoothPrinter(String deviceName) {

		if ((deviceName != null) && (!deviceName.equals(""))) {
			this.btDevice = BluetoothDiscover.getBondedPrinterByName(deviceName);
			if (this.btDevice != null) {
				this.printerName = this.btDevice.getName();
				this.macAddress = this.btDevice.getAddress();
			}
		}
	}

	public boolean isPrinterNull() {

		return this.btDevice == null;
	}

	@Deprecated
	public int open() {

		openConnection();
		return 0;
	}

	public void openConnection() {

		if (this.printerHandler != null) {
			this.printerHandler.obtainMessage(100).sendToTarget();
		}
		thread = new Thread() {

			public void run() {

				try {
					BluetoothPrinter.this.btSocket = BluetoothPrinter.this.btDevice
							.createRfcommSocketToServiceRecord(BluetoothPrinter.this.PRINTER_UUID);
					if (BluetoothPrinter.this.btSocket != null) {
						BluetoothPrinter.this.btSocket.connect();
						Log.i("BluetoothPrinter", "connect establish, wait encryption verify");
					}
					BluetoothPrinter.this.sendStream = BluetoothPrinter.this.btSocket.getOutputStream();
					BluetoothPrinter.this.receiveStream = BluetoothPrinter.this.btSocket.getInputStream();
				} catch (Exception e) {
					Log.i("BluetoothPrinter", "connect failed, wait reflect method or 4.0 method to retry..");
					e.printStackTrace();
					try {
						int sdk = Integer.parseInt(Build.VERSION.SDK);
						Log.i("BluetoothPrinter", "sdk is.." + sdk);
						if (sdk >= 14) {
							BluetoothPrinter.this.btSocket = BluetoothPrinter.this.btDevice
									.createInsecureRfcommSocketToServiceRecord(BluetoothPrinter.this.PRINTER_UUID);
							if (BluetoothPrinter.this.btSocket != null) {
								Log.i("BluetoothPrinter", "4.0 method success, wait connect....");
								BluetoothPrinter.this.btSocket.connect();
								Log.i("BluetoothPrinter", "connect establish, wait encryption verify");
							}
						} else {
							Method method = BluetoothPrinter.this.btDevice.getClass().getMethod("createRfcommSocket", new Class[] { Integer.TYPE });
							BluetoothPrinter.this.btSocket = ((BluetoothSocket) method.invoke(BluetoothPrinter.this.btDevice,
									new Object[] { Integer.valueOf(1) }));
							if (BluetoothPrinter.this.btSocket != null) {
								BluetoothPrinter.this.btSocket.connect();
								Log.i("BluetoothPrinter", "reflect success, connect establish, wait encryption verify");
							}
						}
					} catch (Exception e1) {
						Log.i("BluetoothPrinter", "all method connect failed, return.");
						e1.printStackTrace();
						BluetoothPrinter.this.closeConnection();
						return;
					}
				}

				if (BluetoothPrinter.this.needVerify) {
					if (BluetoothPrinter.this.verifyEncryption()) {
						Log.i("BluetoothPrinter", "encryption verify success");
						BluetoothPrinter.this.isConnected = true;
						if (BluetoothPrinter.this.printerHandler != null)
							BluetoothPrinter.this.printerHandler.obtainMessage(101).sendToTarget();
					} else {
						Log.i("BluetoothPrinter", "encryption verify failed");
						BluetoothPrinter.this.closeConnection();
					}

				} else {
					BluetoothPrinter.this.isConnected = true;
					if (BluetoothPrinter.this.printerHandler != null) {
						BluetoothPrinter.this.printerHandler.obtainMessage(101).sendToTarget();
					}
				}

				if (BluetoothPrinter.this.autoReceive) {
					try {
						while (true) {
							int bytes = BluetoothPrinter.this.receiveStream.available();
							if (bytes > 0) {
								byte[] buffer = new byte[bytes];
								BluetoothPrinter.this.receiveStream.available();
								bytes = BluetoothPrinter.this.receiveStream.read(buffer);
								if (BluetoothPrinter.this.printerHandler != null)
									BluetoothPrinter.this.printerHandler.obtainMessage(105, bytes, -1, buffer).sendToTarget();
							}
						}
					} catch (IOException e) {
						if (BluetoothPrinter.this.printerHandler != null) {
							BluetoothPrinter.this.printerHandler.obtainMessage(104).sendToTarget();
						}
					}
				}
			}
		};
		thread.start();
	}

	private boolean verifyEncryption() {

		byte[] tmpData = null;
		int receiveLength = 0;
		try {
			byte[] tmpSend = { 29, 31 };
			this.sendStream.write(tmpSend);
			this.sendStream.flush();

			receiveLength = this.receiveStream.available();
			int testTime = 15;
			while ((receiveLength <= 0) && (testTime-- > 0)) {
				try {
					Thread.sleep(1000L);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				receiveLength = this.receiveStream.available();
				Log.i("BluetoothPrinter", "receiveStream length is : " + receiveLength);
			}

			if (receiveLength > 0) {
				tmpData = new byte[receiveLength];
				this.receiveStream.read(tmpData);
			} else {
				return false;
			}
		} catch (IOException e) {
			e.printStackTrace();
			Log.i("BluetoothPrinter", "receive input Stream error!");
			return false;
		}

		String mac = this.btDevice.getAddress().replaceAll(":", "").toUpperCase();
		char[] tmpChar = mac.toCharArray();
		int CheckSum = 0;
		Log.i("BluetoothPrinter", "btDevice.getAddress() is : " + this.btDevice.getAddress());
		for (int i = 0; i < 12; i++) {
			CheckSum += (tmpChar[i] << 8 * (i % 4));
		}
		Log.i("BluetoothPrinter", "CheckSum is : " + CheckSum);
		CheckSum ^= 1397772884;
		Log.i("BluetoothPrinter", "CheckSum is(after ..) : " + CheckSum);
		byte[] tmpResult = new byte[4];

		for (int j = 0; j < 4; j++) {
			tmpResult[j] = ((byte) (CheckSum >> (3 - j) * 8));
		}
		Log.i("BluetoothPrinter", "receive tmpData[0] is : " + tmpData[0] + ", self tmpResult[0] is: " + tmpResult[0]);
		return tmpData[0] == tmpResult[0];
	}

	@Deprecated
	public int close() {

		closeConnection();
		return 0;
	}

	public void closeConnection() {

		try {
			if (this.btSocket != null) {
				this.btSocket.close();
			}
			this.btDevice = null;
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (this.isConnected) {
			this.isConnected = false;
			if (this.printerHandler != null)
				this.printerHandler.obtainMessage(103).sendToTarget();
		}

		if (thread != null && thread.isAlive()) {
			thread.interrupt();
			thread = null;
		}
	}

	public byte[] receive() {

		byte[] receiveData = null;
		try {
			int i = this.receiveStream.available();

			int testTime = 15;
			while ((i <= 0) && (testTime-- > 0)) {
				try {
					Thread.sleep(100L);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				i = this.receiveStream.available();
			}
			Log.i("BluetoothPrinter", "receive()-->receiveStream length is : " + i);

			receiveData = new byte[i];
			this.receiveStream.read(receiveData);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return receiveData;
	}

	@Deprecated
	public int send(String content) {

		return printText(content);
	}

	public int printText(String content) {

		if (content == null)
			return -1;
		try {
			this.sendStream.write(content.getBytes(this.mEncoding != null ? this.mEncoding : "GBK"));
			this.sendStream.flush();
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}

		return 0;
	}

	public int printImage(String path) {

		if (path != null) {
			printByteData(Utils.bitmap2PrinterBytes(BitmapFactory.decodeFile(path), 0));
		}
		return -1;
	}

	public int printImage(String path, int left) {

		if (path != null) {
			printByteData(Utils.bitmap2PrinterBytes(BitmapFactory.decodeFile(path), left));
		}
		return -1;
	}

	public int printImage(Bitmap bitmap) {

		if (bitmap != null) {
			return printByteData(Utils.bitmap2PrinterBytes(bitmap, 0));
		}
		return -1;
	}

	public int printImageDot(String path, int multiple, int left) {

		if (path != null) {
			return printByteData(Utils.bitmap2PrinterBytesDot(BitmapFactory.decodeFile(path), multiple, left));
		}
		return -1;
	}

	public int printImageDot(Bitmap bitmap, int multiple, int left) {

		if (bitmap != null) {
			return printByteData(Utils.bitmap2PrinterBytesDot(bitmap, multiple, left));
		}
		return -1;
	}

	public int printImage(Bitmap bitmap, int left) {

		if (bitmap != null) {
			return printByteData(Utils.bitmap2PrinterBytes(bitmap, left));
		}
		return -1;
	}

	@Deprecated
	public int send(byte[] content) {

		return printByteData(content);
	}

	private boolean reconnected = false;

	public int printByteData(byte[] content) {

		try {
			if (sendStream != null) {
				reconnected = false;
				this.sendStream.write(content);
				this.sendStream.flush();
			} else {
				if (!reconnected) {
					closeConnection();
					openConnection();
					printByteData(content);
					reconnected = true;
				}
			}

		} catch (IOException e) {
			e.printStackTrace();
			return -1;
		}
		return 0;
	}

	public void init() {

		setPrinter(0);
	}

	public boolean setPrinter(int command) {

		byte[] arrayOfByte = null;
		switch (command) {
		case 0:
			arrayOfByte = new byte[2];
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 64;
			break;
		case 1:
			arrayOfByte = new byte[1];
			arrayOfByte[0] = 0;
			break;
		case 2:
			arrayOfByte = new byte[1];
			arrayOfByte[0] = 12;
			break;
		case 3:
			arrayOfByte = new byte[1];
			arrayOfByte[0] = 10;
			break;
		case 4:
			arrayOfByte = new byte[1];
			arrayOfByte[0] = 13;
			break;
		case 5:
			arrayOfByte = new byte[1];
			arrayOfByte[0] = 9;
			break;
		case 6:
			arrayOfByte = new byte[2];
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 50;
		}

		printByteData(arrayOfByte);
		return true;
	}

	public boolean setPrinter(int command, int value) {

		byte[] arrayOfByte = new byte[3];
		switch (command) {
		case 0:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 74;
			break;
		case 1:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 100;
			break;
		case 2:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 33;
			break;
		case 3:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 85;
			break;
		case 4:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 86;
			break;
		case 5:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 87;
			break;
		case 6:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 45;
			break;
		case 7:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 43;
			break;
		case 8:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 105;
			break;
		case 9:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 99;
			break;
		case 10:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 51;
			break;
		case 11:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 32;
		case 12:
			arrayOfByte[0] = 28;
			arrayOfByte[1] = 80;
		case 13:
			arrayOfByte[0] = 27;
			arrayOfByte[1] = 97;
			if ((value > 2) || (value < 0))
				return false;
			break;
		}
		arrayOfByte[2] = ((byte) value);
		printByteData(arrayOfByte);
		return true;
	}

	public void setCharacterMultiple(int x, int y) {

		byte[] arrayOfByte = new byte[3];
		arrayOfByte[0] = 29;
		arrayOfByte[1] = 33;

		if ((x >= 0) && (x <= 7) && (y >= 0) && (y <= 7)) {
			arrayOfByte[2] = ((byte) (x * 16 + y));
			printByteData(arrayOfByte);
		}
	}

	public void setLeftMargin(int nL, int nH) {

		byte[] arrayOfByte = new byte[4];
		arrayOfByte[0] = 29;
		arrayOfByte[1] = 76;

		arrayOfByte[2] = ((byte) nL);
		arrayOfByte[3] = ((byte) nH);
		printByteData(arrayOfByte);
	}

	public void setPrintModel(boolean isBold, boolean isDoubleHeight, boolean isDoubleWidth, boolean isUnderLine) {

		byte[] arrayOfByte = new byte[3];
		arrayOfByte[0] = 27;
		arrayOfByte[1] = 33;

		int a = 0;
		if (isBold) {
			a += 8;
		}

		if (isDoubleHeight) {
			a += 16;
		}

		if (isDoubleHeight) {
			a += 32;
		}

		if (isDoubleHeight) {
			a += 128;
		}

		arrayOfByte[2] = ((byte) a);
		printByteData(arrayOfByte);
	}

	public void setBarCode(int param1, int param2, int param3, byte type) {

		if ((type == 100) || (type == 101) || (type == 102)) {
			this.two_dimensional_param1 = param1;
			this.two_dimensional_param2 = param2;
			this.two_dimensional_param3 = param3;
		} else {
			byte[] command = new byte[3];
			command[0] = 29;
			command[1] = 119;
			if ((param1 >= 2) && (param1 <= 6))
				command[2] = ((byte) param1);
			else {
				command[2] = 2;
			}
			printByteData(command);

			command[0] = 29;
			command[1] = 104;
			if ((param2 >= 1) && (param2 <= 255))
				command[2] = ((byte) param2);
			else {
				command[2] = -94;
			}
			printByteData(command);

			command[0] = 29;
			command[1] = 72;
			if ((param3 >= 0) && (param3 <= 3))
				command[2] = ((byte) param3);
			else {
				command[2] = 0;
			}
			printByteData(command);
		}
		this.currentBarCodeType = type;
	}

	public void setTitle(String title, String subTitle, Bitmap logo) {

		this.companyTitle = title;
		this.companySubTitle = subTitle;
		if (logo != null) {
			if (logo.getWidth() > 200)
				this.companyLogo = Utils.compressBitmap(logo, 100);
			else
				this.companyLogo = logo;
		} else
			this.companyLogo = null;
	}

	public void printTitle() {

		if ((this.companyTitle == null) && (this.companySubTitle == null) && (this.companyLogo == null)) {
			return;
		}

		PrintGraphics pg = new PrintGraphics();
		pg.init(getCurrentPrintType());

		int titleTextSize = 0;
		float titlePX = 0.0F;

		if (this.companyTitle != null) {
			titleTextSize = 40;
			titlePX = this.companyTitle.length() * pg.getCharacterWidth(titleTextSize);
			while (titlePX > pg.getWidth() - (this.companyLogo != null ? this.companyLogo.getWidth() : 0)) {
				titlePX = this.companyTitle.length() * pg.getCharacterWidth(titleTextSize--);
			}
			pg.setTextSize(titleTextSize);
		}

		if (this.companyLogo != null) {
			Log.i("BluetoothPrinter", "companyLogo.getWidth() is :" + this.companyLogo.getWidth() + "companyLogo.getHeight() is : "
					+ this.companyLogo.getHeight());

			if (this.companyTitle != null) {
				pg.drawImage((pg.getWidth() - this.companyLogo.getWidth() - titlePX) / 2.0F, 10.0F, this.companyLogo);
				pg.drawText((pg.getWidth() - this.companyLogo.getWidth() - titlePX) / 2.0F + this.companyLogo.getWidth() + 5.0F,
						this.companyLogo.getHeight() + 5, this.companyTitle);
			} else {
				pg.drawImage((pg.getWidth() - this.companyLogo.getWidth()) / 2, 0.0F, this.companyLogo);
			}
		} else if (this.companyTitle != null) {
			pg.drawText((pg.getWidth() - titlePX) / 2.0F, 40.0F, this.companyTitle);
		}

		if (this.companySubTitle != null) {
			int subTitleSize = 25;
			titlePX = this.companySubTitle.length() * pg.getCharacterWidth(subTitleSize);
			while (titlePX > pg.getWidth()) {
				titlePX = this.companySubTitle.length() * pg.getCharacterWidth(subTitleSize--);
			}

			pg.setTextSize(subTitleSize);
			pg.drawText((pg.getWidth() - titlePX) / 2.0F, this.companyLogo != null ? this.companyLogo.getHeight() + 35 : 75, this.companySubTitle);
		}

		printImage(pg.getCanvasImage());
	}

	public void printTable(Table table) {

		if (table == null) {
			return;
		}
		this.tableReg = table.getRegularExpression();
		this.tableData = table.getTableData();
		this.tableColWidth = table.getColumnWidth();
		if (table.hasSeparator()) {
			if (this.currentPrintType == PrinterType.T9)
				printText(this.separator_T9);
			else {
				printText(this.separator_T3);
			}
		}
		for (int m = 0; m < this.tableData.size(); m++) {
			this.tableLine = ((String) this.tableData.get(m)).split(this.tableReg);
			this.unPrintColumnMap = null;
			printTableLine(this.tableLine);
		}
		if (table.hasSeparator())
			if (this.currentPrintType == PrinterType.T9)
				printText(this.separator_T9);
			else
				printText(this.separator_T3);
	}

	private void printTableLine(String[] tableLine) {

		StringBuffer sb = new StringBuffer();
		int sub_length = 0;
		String[] line = tableLine;

		for (int i = 0; i < line.length; i++) {
			line[i] = line[i].trim();

			int index = line[i].indexOf("\n");
			if (index != -1) {
				if (this.unPrintColumnMap == null) {
					this.unPrintColumnMap = new HashMap();
				}
				this.unPrintColumnMap.put(Integer.valueOf(i), line[i].substring(index + 1));

				line[i] = line[i].substring(0, index);
				printTableLine(line);

				printNewLine(line);
				return;
			}

			int length = Utils.getStringCharacterLength(line[i]);
			int col_length = this.tableColWidth.length;
			int col_width = 8;
			if (i < col_length) {
				col_width = this.tableColWidth[i];
			}
			if (length > col_width) {
				sub_length = Utils.getSubLength(line[i], col_width);
				if (this.unPrintColumnMap == null) {
					this.unPrintColumnMap = new HashMap();
				}
				this.unPrintColumnMap.put(Integer.valueOf(i), line[i].substring(sub_length, line[i].length()));

				line[i] = line[i].substring(0, sub_length);
				printTableLine(line);

				printNewLine(line);
				return;
			}
			if (i == 0) {
				sb.append(line[i]);
				for (int j = 0; j < col_width - length; j++)
					sb.append(" ");
			} else {
				for (int j = 0; j < col_width - length; j++) {
					sb.append(" ");
				}
				sb.append(line[i]);
			}
		}

		printText(sb.toString() + "\n");
	}

	private void printNewLine(String[] oldLine) {

		if ((this.unPrintColumnMap != null) && (this.unPrintColumnMap.size() > 0)) {
			String[] newLine = new String[oldLine.length];
			Iterator iterator = this.unPrintColumnMap.entrySet().iterator();
			while (iterator.hasNext()) {
				Map.Entry entry = (Map.Entry) iterator.next();
				Integer key = (Integer) entry.getKey();
				String value = (String) entry.getValue();
				if (key.intValue() < oldLine.length) {
					newLine[key.intValue()] = value;
				}
			}
			this.unPrintColumnMap = null;

			for (int i = 0; i < newLine.length; i++) {
				if ((newLine[i] == null) || (newLine[i] == "")) {
					newLine[i] = " ";
				}
			}

			printTableLine(newLine);
		}
	}
}
